package com.ringtheweb.agi.services.impl;

import java.io.IOException;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.interceptor.Interceptors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.asteriskjava.manager.AuthenticationFailedException;
import org.asteriskjava.manager.ManagerConnection;
import org.asteriskjava.manager.ManagerConnectionFactory;
import org.asteriskjava.manager.TimeoutException;
import org.asteriskjava.manager.action.OriginateAction;
import org.asteriskjava.manager.response.ManagerResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;

import com.ringtheweb.agi.call.CallParameter;
import com.ringtheweb.agi.services.api.IPlayListCallManager;
import com.ringtheweb.common.configuration.ConfigurationFactory;
import com.ringtheweb.common.configuration.IConfiguration;
import com.ringtheweb.model.PhoneNumber;
import com.ringtheweb.model.PlayList;
import com.ringtheweb.persistence.dao.IPlayListDAO;

/**
 * EJB implementation of {@link IPlayListCallManager}
 * @author ldewavri
 *
 */
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class PlayListCallManager implements IPlayListCallManager {
	
	private ManagerConnection managerConnection;
	
	private IConfiguration configuration = ConfigurationFactory.getInstance();
	
	private Log LOG = LogFactory.getLog(PlayListCallManager.class);
	
	
	@Autowired private IPlayListDAO playListDAO;
	
	
	public PlayListCallManager() {
        ManagerConnectionFactory factory = new ManagerConnectionFactory(
                configuration.getString("asterisk.manager.host"),
                configuration.getInt("asterisk.manager.port"),
                configuration.getString("asterisk.manager.username"),
                configuration.getString("asterisk.manager.password"));
        this.managerConnection = factory.createManagerConnection();

	}
	

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void play(Long playListId) {
		
		PlayList playList = playListDAO.findById(playListId, false);
		PhoneNumber phoneNumber = playList.getPhoneNumber();
		
		try {
	        OriginateAction originateAction;
	        ManagerResponse originateResponse;

	        originateAction = new OriginateAction();
	        // TODO : delegate to a router that sets Channel according to number type
	        // Example of channel : SIP/freephonie_outbound/0112345678
	        originateAction.setChannel(configuration.getString("SIP"+configuration.getString("outbound.isdn.context"))+
	        		"/"+phoneNumber.getNumber());
	        // Context to reach agi server
	        originateAction.setContext(configuration.getString("agi.context"));
	        // Set extension in context
	        originateAction.setExten(configuration.getString("agi.default.extension"));
	        originateAction.setPriority(new Integer(1));
	        originateAction.setTimeout(new Integer(30000));
	        originateAction.setVariable(CallParameter.PLAY_LIST_ID.toString(),
	        		String.valueOf(playListId.longValue()));

	        // connect to Asterisk and log in
	        managerConnection.login();

	        // send the originate action and wait for a maximum of 30 seconds for Asterisk
	        // to send a reply
	        originateResponse = managerConnection.sendAction(originateAction, 30000);

	        // print out whether the originate succeeded or not
	        LOG.debug(String.format("Asterisk response : %s ",originateResponse.getResponse()));

	        // and finally log off and disconnect
	        managerConnection.logoff();	
		}
		catch(TimeoutException e) {
			LOG.error(String.format("A timeout occurred when connecting to asterisk manager at '%s' "+
					managerConnection.getHostname()),e);
		}
		catch(AuthenticationFailedException e) {
			LOG.error("Unable to connect to asterisk manager, check connection parameters",e);
		}
		catch(IOException e){
			LOG.error("IOException occured for a connection to asterisk manager",e);
		}


		
		
	}

}
